<template>
  <div></div>
</template>

<script setup>
// Promise A+ 规范 是 JavaScript 中 Promise 的实现标准，它定义了 Promise 的行为和接口，确保不同实现之间的一致性。

/**
 * 1.Promise的使用方法
 */
const promise = new Promise((resolve, rejects) => {
  if (Math.random() * 0.5) {
    resolve("Success!");
  } else {
    rejects("Failure!");
  }
});

promise
  .then(
    (value) => {
      console.log(value);
    },
    (error) => {
      // 接受错误信息的方法1
      console.log(error);
    }
  )
  .catch((error) => {
    // 接受错误信息的方法2
    console.log(error);
  });

/////////////////////////////////////////
/**
 * 2.手写promise 重点！
 */
// 基础定义
// 定义promise的三种状态
const PENDING_STATE = "pending";
const FULFILLED_STATE = "fulfilled";
const REJECTED_STATE = "rejected";

// 判断是否为函数
function isFunction(fun) {
  // return typeof fun==='function'
  return Object.prototype.toString.call(fun) === "[object Function]";
}

// 判断是否为对象
function isObject(obj) {
  return Object.prototype.toString.call(obj) === "[object Object]";
}

// promise 构造器
/**
 * 判断fun是不是函数。定义边界
 * 1.先定义这个类构造器
 */
function MiaoPromise(fun) {
  // 2.定义成功/、失败之后的回调
  this.onFulfiledCallbacks = []; // 成功后的回调
  this.onRejectedCallbacks = []; // 失败后的回调

  this.state = PENDING_STATE;
  //
  this.value = void 0;

  // 定义resolve
  const resolve = (value) => {
    // 具体实现
    // 状态由pending->fulfilled
    // if (this.state === PENDING_STATE) {
    //   this.state = FULFILLED_STATE;
    //   this.value = value;

    //   // 发布
    //   this.onFulfiledCallbacks.forEach((callback) => {
    //     callback(value);
    //   });
    // }
    resolutionProcedure(this, value);
  };

  const resolutionProcedure = function (promise, x) {
    // 判断是否是自身
    if(x ===promise){
        return reject(
            new TypeError('The promise and the value refer to the same object!')
        )
    }

    // 判断是否是promise,从MiaoPromise实例化来的
    if(x instanceof MiaoPromise){
        return x.then(resolve,reject)
    }
    // 状态由pending->fulfilled
    if (promise.state === PENDING_STATE) {
      promise.state = FULFILLED_STATE;
      promise.value = x;

      // 发布
      promise.onFulfiledCallbacks.forEach((callback) => {
        callback(x);
      });
    }
  };

  // 定义reject
  const reject = (reason) => {
    // 状态由pending->rejected
    if (this.state === PENDING_STATE) {
      this.state = REJECTED_STATE;
      this.value = reason;

      // 发布
      this.onRejectedCallbacks.forEach((callback) => {
        callback(reason);
      });
    }
  };

  try {
    fun(resolve, reject);
  } catch (e) {
    reject(e);
  }
}

MiaoPromise.prototype.then = function (onFulfiled, onRejected) {
  onFulfiled && this.onFulfiledCallbacks.push(onFulfiled);
  onRejected && this.onRejectedCallbacks.push(onRejected);
  //   支持链式调用
  return this;
};

// 测试
const promise2 = new MiaoPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("Success!!");
  }, 1000);
});

promise2.then((value) => {
  console.log(value);
});
</script>